/**
 * <html>
 * <body>
 *  <P> Copyright 2014 JasonInternational Ucanx</p>
 *  <p> All rights reserved.</p>
 *  <p> Created on 20170828</p>
 *  <p> Created by Jason</p>
 *  </body>
 * </html>
 */
package cn.ucaner.pay.common.framework.spring.ext;

import java.util.Map;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
* 提供 Spring的扩展工具类 可在任何层调用getBean得到Spring bean 
* @Package：cn.ucaner.framework.common.spring.ext   
* @ClassName：SpringContextHolder   
* @Description：   <p> 提供 Spring的扩展工具类 可在任何层调用getBean得到Spring bean </p>
* @Author： - DaoDou 
* @CreatTime：2017年8月28日 下午4:56:46   
* @Modify By：   
* @ModifyTime：  
* @Modify marker：   
* @version    V1.0
 */
public class SpringContextHolder implements ApplicationContextAware {
	
	/**
	 * <p>
	 * 定义一个引用org.springframework.context.ApplicationContext的引用
	 * </p>
	 */
	private static ApplicationContext applicationContext = null;

	/*
	 * 实现ApplicationContextAware接口, 注入Context到静态变量中. (non-Javadoc)
	 * 
	 * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.
	 * ApplicationContext)
	 */
	public void setApplicationContext(ApplicationContext applicationContext) {

		if (SpringContextHolder.applicationContext != null) {
		}
		SpringContextHolder.applicationContext = applicationContext; // NOSONAR
		//XmlWebApplicationContext con = (XmlWebApplicationContext) applicationContext;
		//ConfigurableListableBeanFactory fc = con.getBeanFactory();
		//System.out.println(fc.toString());
	}

	public static void setApplicationContextTest(ApplicationContext applicationContext) {

		if (SpringContextHolder.applicationContext != null) {
		}
		SpringContextHolder.applicationContext = applicationContext; // NOSONAR
	}

	/**
	 * 实现DisposableBean接口,在Context关闭时清理静态变量.
	 * 
	 * @throws Exception
	 */
	public void destroy() throws Exception {
		SpringContextHolder.clear();
	}

	/**
	 * 取得存储在静态变量中的ApplicationContext.
	 * 
	 * @return
	 */
	public static ApplicationContext getApplicationContext() {
		assertContextInjected();
		return applicationContext;
	}

	/**
	 * <p>
	 * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
	 * </p>
	 * 
	 * @param name
	 *            springbean 的id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getBean(String name) {
		assertContextInjected();
		return (T) applicationContext.getBean(name);
	}

	/**
	 * <p>
	 * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
	 * </p>
	 * @param requiredType
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getBean(Class<T> requiredType) {
		assertContextInjected();
		Map<String, ?> beans = applicationContext.getBeansOfType(requiredType);

		T bean = null;
		if (beans != null) {
			bean = (T) beans.get(beans.keySet().iterator().next());
		}
		return bean;
	}

	/**
	 * <p>
	 * 从静态变量applicationContext中取得clazz类型bean的Map集合
	 * </p>
	 * @param clazz
	 * @return
	 */
	public static Map<String, ?> getBeansOfType(Class<?> clazz) {
		assertContextInjected();
		Map<String, ?> beans = applicationContext.getBeansOfType(clazz);
		return beans;
	}

	/**
	 * <p>
	 * 清除SpringContextHolder中的ApplicationContext为Null.
	 * </p>
	 */
	public static void clear() {
		applicationContext = null;
	}

	/**
	 * <p>
	 * 检查ApplicationContext不为空.为空抛出异常:IllegalStateException
	 * </p>
	 */
	private static void assertContextInjected() {
		if (applicationContext == null) {
			throw new IllegalStateException("applicaitonContext未注入,请在spring.xml中定义SpringContextHolder");
		}
	}

}
